﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Runtime.InteropServices;
using mshtml;

namespace SyncCommon
{
    public class WebBrowserOp
    {
        public  WebBrowser innerBrowser = null;

        [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool InternetSetCookie(string IpszUrlName, string IbszCookieName, string IpszCookieData);

        public event WebBrowserDocumentCompletedEventHandler Completed;
        public event WebBrowserNavigatedEventHandler Navigated;
        public IBrowserForm form;
        public HouseInfo HouseInformation { get; set; }

        public WebBrowserOp(WebBrowser browser,IBrowserForm bf)
        {
            innerBrowser = browser;
            form = bf;
            innerBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(innerBrowser_DocumentCompleted);
            innerBrowser.Navigated += new WebBrowserNavigatedEventHandler(innerBrowser_Navigated);
            innerBrowser.Navigating += new WebBrowserNavigatingEventHandler(innerBrowser_Navigating);
        }

        void innerBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            //form.ShowLoading();
        }

        void innerBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            if (Navigated != null)
            {
                this.Navigated(this, e);
            }
        }

        private int interval = 1000;

        public int CustomerInterval
        {
            get
            {
                return interval;
            }
            set
            {
                interval = value;
            }
        }

        void innerBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (this.innerBrowser.ReadyState < WebBrowserReadyState.Complete) return;
            //form.StopLoading();
            Timer t = new Timer();
            t.Interval = CustomerInterval;
            t.Tick += new EventHandler(t_CompleteTick);
            t.Start();
            
        }

        void t_CompleteTick(object sender, EventArgs e)
        {
            try
            {
                if (Completed != null)
                {
                    if (this.innerBrowser != null)
                    {
                        this.Completed(this, new WebBrowserDocumentCompletedEventArgs(this.innerBrowser.Url));
                    }
                }
            }
            catch
            { } 
            (sender as Timer).Stop();
        }

        public void Navigate(string url)
        {
            innerBrowser.Navigate(url);
        }


        /// <summary>
        /// 设置HTML控件显示文本，根据控件NAME值
        /// </summary>
        /// <param name="web">WebBrowser对象</param>
        /// <param name="strtype">控件类型</param>
        /// <param name="strname">控件NAME值</param>
        /// <param name="strvalue">控件显示文本</param>
        public void SetValueByType(string strtype, string strname, string strvalue)
        {
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("name").ToString() == strname)
                {
                    elem.SetAttribute("value", strvalue);
                }
            }
        }

        public void SetValueByName(string strName, string strValue)
        {
            HtmlElement elem = GetTelementByName(strName);
            if (elem != null)
            {
                elem.SetAttribute("value", strValue);
            }
        }


        public void SetValueByName_BigBrother(string strName, string strValue)
        {
            HtmlElement elem = GetTelementByName(strName);
            if (elem != null)
            {
                HtmlElement el = elem.Parent.FirstChild;
                if (el != null)
                {
                    el.SetAttribute("value", strValue);
                }
            }
        }

        /// <summary>
        /// 设置HTML控件显示文本，根据空间ID值
        /// </summary>
        /// <param name="web">WebBrowser对象</param>
        /// <param name="strtype">控件类型</param>
        /// <param name="strid">控件ID值</param>
        /// <param name="strvalue">控件显示文本</param>
        public void SetValueByID(string strID, string strValue)
        {
            HtmlElement elem = this.innerBrowser.Document.GetElementById(strID);
            if (elem != null)
            {
                elem.SetAttribute("value", strValue);
            }
        }


        public void SetHtmlByID(string strID, string strValue)
        {
            HtmlElement elem = this.innerBrowser.Document.GetElementById(strID);
            if (elem != null)
            {
                elem.InnerHtml = strValue;
            }
        }

        public void SetHtmlByIDWithoutBlank(string strID, string strValue)
        {
            HtmlElement elem = this.innerBrowser.Document.GetElementById(strID);
            if (elem != null)
            {
                elem.OuterText = strValue;
            }
        }

        public void SetTextByID(string strID, string strValue)
        {
            HtmlElement elem = this.innerBrowser.Document.GetElementById(strID);
            if (elem != null)
            {
                elem.InnerText = strValue;
            }
        }


        /// <summary>
        /// 激发HTML事件，根据空间ID值
        /// </summary>
        /// <param name="web">WebBrowser对象</param>
        /// <param name="strtype">控件类型</param>
        /// <param name="strid">控件ID值</param>
        /// <param name="exname">控件事件名称</param>
        public void RaiseOpByID(string strID, string opName, params object[] param)
        {

            HtmlElement elem = this.innerBrowser.Document.GetElementById(strID);
            if (elem != null)
            {
                elem.InvokeMember(opName, param);
            }
        }
        /// <summary>
        /// 激发HTML事件，根据空间NAME值
        /// </summary>
        /// <param name="web">WebBrowser对象</param>
        /// <param name="strtype">控件类型</param>
        /// <param name="strname">控件NAME值</param>
        /// <param name="exname">控件事件名称</param>
        public void RaiseOpByType(string strType, string strName, string opName, params object[] param)
        {
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strType);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("name").ToString() == strName)
                {
                    elem.InvokeMember(opName);
                }
            }
        }


        /// <summary>
        /// 执行当前HTML页中用脚本语言定义的函数
        /// </summary>
        /// <param name="web">WebBrowser对象</param> 
        /// <param name="strSrc">控件NAME值</param>
        /// <param name="exname">控件事件名称</param>
        public void RaiseOpByName(string strName, string opName, params object[] param)
        {
            HtmlElement el = GetTelementByName(strName);
            if (el != null)
            {
                el.InvokeMember(opName);
            }
        }

        public void RaiseOpByAttribute(string strAttr, string strAttrVal, string opName, params object[] param)
        {
            HtmlElementCollection elemlist = this.innerBrowser.Document.All;
            foreach (HtmlElement el in elemlist)
            {
                if (el.GetAttribute(strAttr) == strAttrVal)
                {
                    el.InvokeMember(opName);
                }
            }
        }

        /// <summary>
        /// 设置HTML控件的属性,针对radiobutton和checkbox
        /// </summary>
        /// <param name="web">WebBrowser对象</param>
        /// <param name="strtype">控件类型</param>
        /// <param name="strname">控件id</param>
        /// <param name="ischeck">true为选中,false为勾掉</param>
        public void CheckByID(string strID, bool ischeck)
        {
            string strtype = "input";
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("id").ToString() == strID)
                {
                    elem.SetAttribute("checked", ischeck.ToString());
                }
            }
        }

        public void CheckByName(string strName, bool ischeck)
        {
            string strtype = "input";
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("name").ToString() == strName)
                {
                    elem.SetAttribute("checked", ischeck.ToString());
                }
            }
        }

        public void CheckByName_Value(string strName,string strVal ,bool ischeck)
        {
            string strtype = "input";
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("name").ToString() == strName
                    && elem.GetAttribute("value").ToString() == strVal)
                {
                    elem.SetAttribute("checked", ischeck.ToString());
                }
            }
        }

        public void SelectByName_Value(string strName, string strValue)
        {
            string strtype = "select";
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("name").ToString() == strName)
                {
                    foreach (HtmlElement child in elem.Children)
                    {
                        if (child.GetAttribute("value").ToString() == strValue)
                        {
                            child.SetAttribute("selected", "selected");
                        }
                    }

                }
            }
        }


        public void SelectByName_Text(string strName, string strText)
        {
            string strtype = "select";
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("name").ToString() == strName)
                {
                    foreach (HtmlElement child in elem.Children)
                    {
                        if ((child.InnerText ?? "").Trim() == strText)
                        {
                            child.SetAttribute("selected", "selected");
                        }
                    }

                }
            }
        }

        /// <summary>
        /// 在当前HTML页中选中Select中与定义的索引值相同的项
        /// </summary>
        /// <param name="web">WebBrowser对象</param>
        /// <param name="strtype">控件类型</param>
        /// <param name="strid">控件NAME值</param>
        /// <param name="strvalue">要选中的索引值</param>
        public void SelectByName(string strName, string strIndex)
        {
            string strtype = "select";
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("name").ToString() == strName)
                {
                    elem.SetAttribute("SelectedIndex", strIndex);
                }
            }
        }

        /// <summary>
        /// 在当前HTML页中选中Select中与定义的索引值相同的项
        /// </summary>
        /// <param name="web">WebBrowser对象</param>
        /// <param name="strtype">控件类型</param>
        /// <param name="strid">控件NAME值</param>
        /// <param name="strvalue">要选中的索引值</param>
        public void  SelectByID_Value(string strID, string strValue)
        {
            HtmlElement el = this.innerBrowser.Document.GetElementById(strID);
            if (el != null)
            {
                foreach (HtmlElement child in el.Children)
                {
                    if (child.GetAttribute("value").ToString() == strValue)
                    {
                        child.SetAttribute("selected", "selected");
                    }
                }
            }

        }

        public void SelectByID(string strID, string strIndex)
        {
            string strtype = "select";
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("id").ToString() == strID)
                {
                    elem.SetAttribute("SelectedIndex", strIndex);
                }
            }
        }

        /// <summary>
        /// 在当前HTML页中选中Select中与定义的索引值相同的项
        /// </summary>
        /// <param name="web">WebBrowser对象</param>
        /// <param name="strtype">控件类型</param>
        /// <param name="strid">控件NAME值</param>
        /// <param name="strvalue">没用的</param>
        public void Select(string strtype, string strid, string strvalue)
        {
            HtmlElementCollection elemlist = this.innerBrowser.Document.GetElementsByTagName(strtype);
            foreach (HtmlElement elem in elemlist)
            {
                if (elem.GetAttribute("name").ToString() == strid)
                {
                    elem.SetAttribute("Options[22]", "selected");
                }
            }
        }

        private HtmlElement GetTelementByName(string name)
        {
            HtmlElementCollection elemlist = this.innerBrowser.Document.All;
            foreach (HtmlElement el in elemlist)
            {
                if (el.Name.ToLower() == name.ToLower())
                {
                    return el;
                }
            }
            return null;
        }

        public void SetValueByAttribute(string strAttr,string strAttrVal,string val)
        {
            HtmlElementCollection elemlist = this.innerBrowser.Document.Forms[0].All;
            foreach (HtmlElement el in elemlist)
            {
                if (el.GetAttribute(strAttr) == strAttrVal)
                {
                    el.SetAttribute("value", val);
                }
            }
        }

        public void SetValueByLikeAttribute(string strAttr, string strAttrVal, string val)
        {
            HtmlElementCollection elemlist = this.innerBrowser.Document.Forms[0].All;
            foreach (HtmlElement el in elemlist)
            {
                if (el.GetAttribute(strAttr).Contains(strAttrVal))
                {
                    el.SetAttribute("value", val);
                }
            }
        }

        public void SetHtmlByAttribute(string strAttr, string strAttrVal, string val,int index)
        {
              HtmlWindow w = this.innerBrowser.Document.Window.Frames[index]; 
              SetHtmlByAttributeInternal(w, strAttr, strAttrVal, val);
        }

        public void ExcuteScript(string script)
        {
            try
            {
                ((IHTMLDocument2)this.innerBrowser.Document.DomDocument).parentWindow.execScript(script, "javascript");
            }
            catch
            { }
            //HtmlElement body = this.innerBrowser.Document.GetElementsByTagName("body")[0];//我这里获取BODY为，想放到最后。
            
            //HtmlElement hele = this.innerBrowser.Document.CreateElement("script");

            //hele.OuterHtml = "alter('ok')";// script;
            
            //body.AppendChild(hele);
        }

        public void SetHtmlByAttribute(string strAttr, string strAttrVal, string val, string frameName)
        {
            HtmlWindow w = this.innerBrowser.Document.Window.Frames[frameName];
            SetHtmlByAttributeInternal(w, strAttr, strAttrVal, val);
        }

        public void SetHtmlByAttribute(string strAttr, string strAttrVal, string val)
        {
            SetHtmlByAttributeInternal(this.innerBrowser.Document.Window,strAttr, strAttrVal, val);
        }

        private void SetHtmlByAttributeInternal(HtmlWindow w,string strAttr, string strAttrVal, string val)
        {
            HtmlElementCollection elemlist = w.Document.All;
            foreach (HtmlElement el in elemlist)
            {
                if (el.GetAttribute(strAttr) == strAttrVal)
                {
                    el.InnerHtml = val;
                }
            }
        }
        public void SetCKEditorHtml(string content)
        {
            if (this.innerBrowser.Document.Window.Frames.Count > 0)
            {
                HtmlWindow w = this.innerBrowser.Document.Window.Frames[0];
                if (w != null)
                {
                    w.Document.Body.InnerHtml = content;
                }
            }
        }

        public void SetCKEditorHtml(string iframeID,string content)
        {
            if (this.innerBrowser.Document.Window.Frames.Count > 0)
            {
                try
                {
                    HtmlWindow w = this.innerBrowser.Document.Window.Frames[iframeID];
                    if (w != null)
                    {
                        w.Document.Body.InnerHtml = content;
                    }
                }
                catch
                { }
            }
        }

        public HtmlElement FindElementByAttr(string attr, string val, HtmlWindow w)
        {
            try
            {
                HtmlElementCollection elemlist = w.Document.All;
                foreach (HtmlElement el in elemlist)
                {
                    if (el.GetAttribute(attr) == val)
                    {
                        return el;
                    }
                }
                if (w.Frames.Count > 0)
                {
                    foreach (HtmlWindow c in w.Frames)
                    {
                        HtmlElement t = FindElementByAttr(attr, val, c);
                        if (t != null)
                        {
                            return t;
                        }
                    }
                }
            }
            catch
            {

            }
            return null;
        }

        public void SetAllFrameValByAttr(string attr,string val, string content)
        {
            HtmlElement el = FindElementByAttr(attr, val, this.innerBrowser.Document.Window);
            if (el != null)
            {
                el.InnerHtml = content;
            }
        }
    }
}
